package com.crawler.harbour.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

@Component
public class JacksonObjectMapper extends ObjectMapper {
	private static final long serialVersionUID = -624755482354300157L;

	
	public JacksonObjectMapper() {
		//super.setDateFormat(DATE_FORMAT);
		super.setTimeZone(TimeZone.getTimeZone("GMT+8"));
		super.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
		// 设置时间为 ISO-8601 日期
		//super.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
		// 设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
		super.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES);
		super.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
		// 设置将驼峰命名法转换成下划线的方式输入输出
	//	super.setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
		super.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
		super.disable(SerializationFeature.WRITE_NULL_MAP_VALUES);
		// 设定是否使用Enum的toString函数来读取Enum, 为False时使用Enum的name()函数来读取Enum,
		super.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
		// 如果输入不存在的字段时不会报错
		super.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
		// 使用默认的Jsckson注解
		super.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
		
		this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
            @Override
            public void serialize(Object value, JsonGenerator gen, SerializerProvider sp) throws IOException {
            	Class<?> fieldType = getFieldType(gen.getCurrentValue(), gen.getOutputContext().getCurrentName());
                gen.getOutputContext().getCurrentIndex();
                if(Number.class.isAssignableFrom(fieldType)){
                	gen.writeNumber(BigDecimal.ZERO);
                }
                else if(List.class.isAssignableFrom(fieldType)){
                	gen.writeObject(new ArrayList<>());
                }
                else if(String.class.isAssignableFrom(fieldType)){                	
                	gen.writeString("");
                }
                else{
                	gen.writeObject(value);
                }
                
            }
        });
	}
	
	/**
	 * 获取字段类型
	 * @param object
	 * @param key
	 * @return
	 */
	public static Class<?> getFieldType(Object object, String key){
		String[] arr = key.split("_");
		StringBuffer stringBuffer = new StringBuffer();
		for(int i=0; i<arr.length; i++){
			String str = arr[i];
			if(i==0){
				stringBuffer.append(str);
			}
			else{
				stringBuffer.append(str.substring(0, 1).toUpperCase());				
				stringBuffer.append(str.substring(1));
			}
		}
		key = stringBuffer.toString();
		
		Class<?> clz = object.getClass();
        // 获取实体类的所有属性，返回Field数组  
		Field[] fields = clz.getDeclaredFields();
		for(Field field :fields){
			if(field.getName().equals(key)){
				return field.getType();
			}
		}
		return String.class;
	}
	
	

}